#include "net_context.h"
#include "base_ip.h"

using namespace usnet;

bool BaseIP::InitARPImpl()
{
    auto ctx = NetContext::GetContext();
    ifcfg_ = ctx->GetIfconfig(laddr_);
    if (ifcfg_ == nullptr) {
        LOG_ERROR(ctx, "failed to get ifconfig");
        return false;
    }
    memcpy(laddr_->eth_addr_, ifcfg_->eth_addr_, sizeof(laddr_->eth_addr_));
    return ctx->CreateARPImpl(ifcfg_, laddr_);
}

bool BaseIP::InitEthImpl()
{
    auto ctx = NetContext::GetContext();
    if (ctx->GetEthAddr(ifcfg_, raddr_) == false) {
        return false;
    }
    if (laddr_->inet_proto_ == InetProto::IPv4) {
        eth_impl_ = EthImpl::MakeUnique(PPT::IPv4, laddr_, raddr_, ifcfg_);
        if (eth_impl_ == nullptr) {
            LOG_ERROR(ctx, "failed to create EthImpl instance");
            return false;
        }
        if (eth_impl_->AddFilter(FilterLevel::IP4_FULL) ==  false) {
            LOG_ERROR(ctx, "failed to set filter");
            return false;
        }
    }
    if (laddr_->inet_proto_ == InetProto::IPv6) {
        eth_impl_ = EthImpl::MakeUnique(PPT::IPv6, laddr_, raddr_, ifcfg_);
        if (eth_impl_ == nullptr) {
            LOG_ERROR(ctx, "failed to create EthImpl instance");
            return false;
        }
        // if (eth_impl_->AddFilter(FilterLevel::IP6_FULL) ==  false) {
        //     LOG_ERROR(ctx, "failed to set filter");
        //     return false;
        // }
    }
    
    return true;
}